home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / Glypha III Src / Code / Graphics.c < prev    next >
Encoding:
Text File  |  1995-01-30  |  27.8 KB  |  1,017 lines  |  [TEXT/MPCC]

  1.  
  2. //============================================================================
  3. //----------------------------------------------------------------------------
  4. //                                    Graphics.c
  5. //----------------------------------------------------------------------------
  6. //============================================================================
  7.  
  8.  
  9. #include "Externs.h"
  10. #include <Palettes.h>
  11.  
  12.  
  13. #define kUpperEyeHeight            100
  14. #define kLowerEyeHeight            200
  15. #define kNumLightningPts        8
  16. #define kMaxNumUpdateRects        32
  17.  
  18.  
  19. void QuickUnionRect (Rect *, Rect *, Rect *);
  20. void CheckPlayerWrapAround (void);
  21. void DrawHand (void);
  22. void DrawEye (void);
  23. void DrawPlayer (void);
  24. void CheckEnemyWrapAround (short);
  25. void DrawEnemies (void);
  26.  
  27.  
  28. Rect        backSrcRect, workSrcRect, obSrcRect, playerSrcRect;
  29. Rect        numberSrcRect, idleSrcRect, enemyWalkSrcRect, enemyFlySrcRect;
  30. Rect        obeliskRects[4], playerRects[11], numbersSrc[11], numbersDest[11];
  31. Rect        updateRects1[kMaxNumUpdateRects], updateRects2[kMaxNumUpdateRects];
  32. Rect        flameSrcRect, flameDestRects[2], flameRects[4], eggSrcRect;
  33. Rect        platformSrcRect, platformCopyRects[9], helpSrcRect, eyeSrcRect;
  34. Rect        helpSrc, helpDest, handSrcRect, handRects[2], eyeRects[4];
  35. Point        leftLightningPts[kNumLightningPts], rightLightningPts[kNumLightningPts];
  36. CGrafPtr    backSrcMap, workSrcMap, obeliskSrcMap, playerSrcMap, eyeSrcMap;
  37. CGrafPtr    numberSrcMap, idleSrcMap, enemyWalkSrcMap, enemyFlySrcMap;
  38. CGrafPtr    flameSrcMap, eggSrcMap, platformSrcMap, helpSrcMap, handSrcMap;
  39. GrafPtr        playerMaskMap, enemyWalkMaskMap, enemyFlyMaskMap, eggMaskMap;
  40. GrafPtr        handMaskMap, eyeMaskMap;
  41. RgnHandle    playRgn;
  42. short        numUpdateRects1, numUpdateRects2;
  43. Boolean        whichList, helpOpen, scoresOpen;
  44.  
  45. extern    handInfo    theHand;
  46. extern    eyeInfo        theEye;
  47. extern    prefsInfo    thePrefs;
  48. extern    playerType    thePlayer;
  49. extern    enemyType    theEnemies[];
  50. extern    Rect        enemyRects[24];
  51. extern    WindowPtr    mainWindow;
  52. extern    long        theScore, wasTensOfThousands;
  53. extern    short        livesLeft, levelOn, numEnemies;
  54. extern    Boolean        evenFrame;
  55.  
  56.  
  57. //==============================================================  Functions
  58. //--------------------------------------------------------------  DrawPlatforms
  59.  
  60. void DrawPlatforms (short howMany)
  61. {
  62.     if (howMany > 3)
  63.     {
  64.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  65.                 &((GrafPtr)backSrcMap)->portBits, 
  66.                 &platformCopyRects[2], &platformCopyRects[7], srcCopy, playRgn);
  67.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  68.                 &((GrafPtr)workSrcMap)->portBits, 
  69.                 &platformCopyRects[7], &platformCopyRects[7], srcCopy, playRgn);
  70.         AddToUpdateRects(&platformCopyRects[7]);
  71.         
  72.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  73.                 &((GrafPtr)backSrcMap)->portBits, 
  74.                 &platformCopyRects[4], &platformCopyRects[8], srcCopy, playRgn);
  75.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  76.                 &((GrafPtr)workSrcMap)->portBits, 
  77.                 &platformCopyRects[8], &platformCopyRects[8], srcCopy, playRgn);
  78.         AddToUpdateRects(&platformCopyRects[8]);
  79.     }
  80.     else
  81.     {
  82.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  83.                 &((GrafPtr)backSrcMap)->portBits, 
  84.                 &platformCopyRects[3], &platformCopyRects[7], srcCopy, playRgn);
  85.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  86.                 &((GrafPtr)workSrcMap)->portBits, 
  87.                 &platformCopyRects[7], &platformCopyRects[7], srcCopy, playRgn);
  88.         AddToUpdateRects(&platformCopyRects[7]);
  89.         
  90.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  91.                 &((GrafPtr)backSrcMap)->portBits, 
  92.                 &platformCopyRects[5], &platformCopyRects[8], srcCopy, playRgn);
  93.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  94.                 &((GrafPtr)workSrcMap)->portBits, 
  95.                 &platformCopyRects[8], &platformCopyRects[8], srcCopy, playRgn);
  96.         AddToUpdateRects(&platformCopyRects[8]);
  97.     }
  98.     
  99.     if (howMany > 5)
  100.     {
  101.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  102.                 &((GrafPtr)backSrcMap)->portBits, 
  103.                 &platformCopyRects[0], &platformCopyRects[6], srcCopy, playRgn);
  104.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  105.                 &((GrafPtr)workSrcMap)->portBits, 
  106.                 &platformCopyRects[6], &platformCopyRects[6], srcCopy, playRgn);
  107.         AddToUpdateRects(&platformCopyRects[6]);
  108.     }
  109.     else
  110.     {
  111.         CopyBits(&((GrafPtr)platformSrcMap)->portBits, 
  112.                 &((GrafPtr)backSrcMap)->portBits, 
  113.                 &platformCopyRects[1], &platformCopyRects[6], srcCopy, playRgn);
  114.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  115.                 &((GrafPtr)workSrcMap)->portBits, 
  116.                 &platformCopyRects[6], &platformCopyRects[6], srcCopy, playRgn);
  117.         AddToUpdateRects(&platformCopyRects[6]);
  118.     }
  119. }
  120.  
  121. //--------------------------------------------------------------  ScrollHelp
  122.  
  123. void ScrollHelp (short scrollDown)
  124. {
  125.     OffsetRect(&helpSrc, 0, scrollDown);
  126.     
  127.     if (helpSrc.bottom > 398)
  128.     {
  129.         helpSrc.bottom = 398;
  130.         helpSrc.top = helpSrc.bottom - 199;
  131.     }
  132.     else if (helpSrc.top < 0)
  133.     {
  134.         helpSrc.top = 0;
  135.         helpSrc.bottom = helpSrc.top + 199;
  136.     }
  137.     
  138.     CopyBits(&((GrafPtr)helpSrcMap)->portBits, 
  139.             &(((GrafPtr)mainWindow)->portBits), 
  140.             &helpSrc, &helpDest, srcCopy, 0L);
  141. }
  142.  
  143. //--------------------------------------------------------------  OpenHelp
  144.  
  145. void OpenHelp (void)
  146. {
  147.     Rect        wallSrc, wallDest;
  148.     short        i;
  149.     
  150.     SetRect(&helpSrc, 0, 0, 231, 0);
  151.     helpDest = helpSrc;
  152.     OffsetRect(&helpDest, 204, 171);
  153.     
  154.     SetRect(&wallSrc, 0, 0, 231, 199);
  155.     OffsetRect(&wallSrc, 204, 171);
  156.     wallDest = wallSrc;
  157.     
  158.     for (i = 0; i < 199; i ++)
  159.     {
  160.         LogNextTick(1L);
  161.         helpSrc.bottom++;
  162.         helpDest.bottom++;
  163.         wallSrc.bottom--;
  164.         wallDest.top++;
  165.         
  166.         CopyBits(&((GrafPtr)helpSrcMap)->portBits, 
  167.                 &(((GrafPtr)mainWindow)->portBits), 
  168.                 &helpSrc, &helpDest, srcCopy, 0L);
  169.         
  170.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  171.                 &(((GrafPtr)mainWindow)->portBits), 
  172.                 &wallSrc, &wallDest, srcCopy, 0L);
  173.         
  174.         WaitForNextTick();
  175.     }
  176.     helpOpen = TRUE;
  177. }
  178.  
  179. //--------------------------------------------------------------  CloseWall
  180.  
  181. void CloseWall (void)
  182. {
  183.     Rect        wallSrc, wallDest;
  184.     short        i;
  185.     
  186.     SetRect(&wallSrc, 0, 0, 231, 0);
  187.     wallDest = wallSrc;
  188.     OffsetRect(&wallDest, 204, 370);
  189.     OffsetRect(&wallSrc, 204, 171);
  190.     
  191.     for (i = 0; i < 199; i ++)
  192.     {
  193.         wallSrc.bottom++;
  194.         wallDest.top--;
  195.         
  196.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  197.                 &(((GrafPtr)mainWindow)->portBits), 
  198.                 &wallSrc, &wallDest, srcCopy, 0L);
  199.     }
  200. }
  201.  
  202. //--------------------------------------------------------------  OpenHighScores
  203.  
  204. void OpenHighScores (void)
  205. {
  206.     RGBColor    theRGBColor, wasColor;
  207.     Rect        wallSrc, wallDest;
  208.     Rect        scoreSrc, scoreDest;
  209.     Str255        scoreStr;
  210.     short        i, scoreWide;
  211.     
  212.     SetRect(&scoreSrc, 0, 0, 231, 0);
  213.     OffsetRect(&scoreSrc, 204, 171);
  214.     scoreDest = scoreSrc;
  215.     
  216.     SetRect(&wallSrc, 0, 0, 231, 199);
  217.     OffsetRect(&wallSrc, 204, 171);
  218.     wallDest = wallSrc;
  219.     
  220.     SetPort((GrafPtr)workSrcMap);
  221.     PaintRect(&wallSrc);
  222.     
  223.     GetForeColor(&wasColor);
  224.     
  225.     TextFont(geneva);
  226.     TextSize(12);
  227.     TextFace(bold);
  228.     
  229.     Index2Color(132, &theRGBColor);
  230.     RGBForeColor(&theRGBColor);
  231.     MoveTo(scoreSrc.left + 36, scoreSrc.top + 20);
  232.     DrawString("\pGlypha III High Scores");
  233.     
  234.     TextFont(geneva);
  235.     TextSize(9);
  236.     TextFace(bold);
  237.     
  238.     for (i = 0; i < 10; i++)
  239.     {
  240.         Index2Color(133, &theRGBColor);
  241.         RGBForeColor(&theRGBColor);
  242.         NumToString((long)i + 1L, scoreStr);
  243.         MoveTo(scoreSrc.left + 8, scoreSrc.top + 40 + (i * 16));
  244.         DrawString(scoreStr);
  245.         
  246.         Index2Color(128, &theRGBColor);
  247.         RGBForeColor(&theRGBColor);
  248.         MoveTo(scoreSrc.left + 32, scoreSrc.top + 40 + (i * 16));
  249.         DrawString(thePrefs.highNames[i]);
  250.         
  251.         Index2Color(164, &theRGBColor);
  252.         RGBForeColor(&theRGBColor);
  253.         NumToString(thePrefs.highScores[i], scoreStr);
  254.         scoreWide = StringWidth(scoreStr);
  255.         MoveTo(scoreSrc.left + 191 - scoreWide, scoreSrc.top + 40 + (i * 16));
  256.         DrawString(scoreStr);
  257.         
  258.         Index2Color(134, &theRGBColor);
  259.         RGBForeColor(&theRGBColor);
  260.         NumToString(thePrefs.highLevel[i], scoreStr);
  261.         scoreWide = StringWidth(scoreStr);
  262.         MoveTo(scoreSrc.left + 223 - scoreWide, scoreSrc.top + 40 + (i * 16));
  263.         DrawString(scoreStr);
  264.     }
  265.     
  266.     RGBForeColor(&wasColor);
  267.     
  268.     SetPort((GrafPtr)mainWindow);
  269.     
  270.     for (i = 0; i < 199; i ++)
  271.     {
  272.         LogNextTick(1L);
  273.         scoreSrc.bottom++;
  274.         scoreDest.bottom++;
  275.         wallSrc.bottom--;
  276.         wallDest.top++;
  277.         
  278.         CopyBits(&((GrafPtr)workSrcMap)->portBits, 
  279.                 &(((GrafPtr)mainWindow)->portBits), 
  280.                 &scoreSrc, &scoreDest, srcCopy, 0L);
  281.         
  282.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  283.                 &(((GrafPtr)mainWindow)->portBits), 
  284.                 &wallSrc, &wallDest, srcCopy, 0L);
  285.         
  286.         WaitForNextTick();
  287.     }
  288.     
  289.     scoresOpen = TRUE;
  290. }
  291.  
  292. //--------------------------------------------------------------  UpdateLivesNumbers
  293.  
  294. void UpdateLivesNumbers (void)
  295. {
  296.     short        digit;
  297.     
  298.     digit = (livesLeft - 1) / 10;
  299.     digit = digit % 10L;
  300.     if ((digit == 0) && ((livesLeft - 1) < 100))
  301.         digit = 10;
  302.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  303.             &((GrafPtr)backSrcMap)->portBits, 
  304.             &numbersSrc[digit], &numbersDest[0], srcCopy, 0L);
  305.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  306.             &(((GrafPtr)mainWindow)->portBits), 
  307.             &numbersDest[0], &numbersDest[0], srcCopy, 0L);
  308.     
  309.     digit = (livesLeft - 1) % 10;
  310.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  311.             &((GrafPtr)backSrcMap)->portBits, 
  312.             &numbersSrc[digit], &numbersDest[1], srcCopy, 0L);
  313.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  314.             &(((GrafPtr)mainWindow)->portBits), 
  315.             &numbersDest[1], &numbersDest[1], srcCopy, 0L);
  316. }
  317.  
  318. //--------------------------------------------------------------  UpdateScoreNumbers
  319.  
  320. void UpdateScoreNumbers (void)
  321. {
  322.     long        digit;
  323.     
  324.     digit = theScore / 100000L;
  325.     digit = digit % 10L;
  326.     if ((digit == 0) && (theScore < 1000000L))
  327.         digit = 10;
  328.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  329.             &((GrafPtr)backSrcMap)->portBits, 
  330.             &numbersSrc[digit], &numbersDest[2], srcCopy, 0L);
  331.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  332.             &(((GrafPtr)mainWindow)->portBits), 
  333.             &numbersDest[2], &numbersDest[2], srcCopy, 0L);
  334.     
  335.     digit = theScore / 10000L;
  336.     if (digit > wasTensOfThousands)
  337.     {
  338.         livesLeft++;
  339.         UpdateLivesNumbers();
  340.         wasTensOfThousands = digit;
  341.     }
  342.     
  343.     digit = digit % 10L;
  344.     if ((digit == 0) && (theScore < 100000L))
  345.         digit = 10;
  346.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  347.             &((GrafPtr)backSrcMap)->portBits, 
  348.             &numbersSrc[digit], &numbersDest[3], srcCopy, 0L);
  349.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  350.             &(((GrafPtr)mainWindow)->portBits), 
  351.             &numbersDest[3], &numbersDest[3], srcCopy, 0L);
  352.     
  353.     digit = theScore / 1000L;
  354.     digit = digit % 10L;
  355.     if ((digit == 0) && (theScore < 10000L))
  356.         digit = 10;
  357.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  358.             &((GrafPtr)backSrcMap)->portBits, 
  359.             &numbersSrc[digit], &numbersDest[4], srcCopy, 0L);
  360.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  361.             &(((GrafPtr)mainWindow)->portBits), 
  362.             &numbersDest[4], &numbersDest[4], srcCopy, 0L);
  363.     
  364.     digit = theScore / 100L;
  365.     digit = digit % 10L;
  366.     if ((digit == 0) && (theScore < 1000L))
  367.         digit = 10;
  368.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  369.             &((GrafPtr)backSrcMap)->portBits, 
  370.             &numbersSrc[digit], &numbersDest[5], srcCopy, 0L);
  371.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  372.             &(((GrafPtr)mainWindow)->portBits), 
  373.             &numbersDest[5], &numbersDest[5], srcCopy, 0L);
  374.     
  375.     digit = theScore / 10L;
  376.     digit = digit % 10L;
  377.     if ((digit == 0) && (theScore < 100L))
  378.         digit = 10;
  379.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  380.             &((GrafPtr)backSrcMap)->portBits, 
  381.             &numbersSrc[digit], &numbersDest[6], srcCopy, 0L);
  382.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  383.             &(((GrafPtr)mainWindow)->portBits), 
  384.             &numbersDest[6], &numbersDest[6], srcCopy, 0L);
  385.     
  386.     digit = theScore % 10L;
  387.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  388.             &((GrafPtr)backSrcMap)->portBits, 
  389.             &numbersSrc[digit], &numbersDest[7], srcCopy, 0L);
  390.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  391.             &(((GrafPtr)mainWindow)->portBits), 
  392.             &numbersDest[7], &numbersDest[7], srcCopy, 0L);
  393. }
  394.  
  395. //--------------------------------------------------------------  UpdateLevelNumbers
  396.  
  397. void UpdateLevelNumbers (void)
  398. {
  399.     short        digit;
  400.     
  401.     digit = (levelOn + 1) / 100;
  402.     digit = digit % 10L;
  403.     if ((digit == 0) && ((levelOn + 1) < 1000))
  404.         digit = 10;
  405.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  406.             &((GrafPtr)backSrcMap)->portBits, 
  407.             &numbersSrc[digit], &numbersDest[8], srcCopy, 0L);
  408.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  409.             &(((GrafPtr)mainWindow)->portBits), 
  410.             &numbersDest[8], &numbersDest[8], srcCopy, 0L);
  411.     
  412.     digit = (levelOn + 1) / 10;
  413.     digit = digit % 10L;
  414.     if ((digit == 0) && ((levelOn + 1) < 100))
  415.         digit = 10;
  416.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  417.             &((GrafPtr)backSrcMap)->portBits, 
  418.             &numbersSrc[digit], &numbersDest[9], srcCopy, 0L);
  419.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  420.             &(((GrafPtr)mainWindow)->portBits), 
  421.             &numbersDest[9], &numbersDest[9], srcCopy, 0L);
  422.     
  423.     digit = (levelOn + 1) % 10;
  424.     CopyBits(&((GrafPtr)numberSrcMap)->portBits, 
  425.             &((GrafPtr)backSrcMap)->portBits, 
  426.             &numbersSrc[digit], &numbersDest[10], srcCopy, 0L);
  427.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  428.             &(((GrafPtr)mainWindow)->portBits), 
  429.             &numbersDest[10], &numbersDest[10], srcCopy, 0L);
  430. }
  431.  
  432. //--------------------------------------------------------------  GenerateLightning
  433.  
  434. void GenerateLightning (short h, short v)
  435. {
  436.     #define kLeftObeliskH        172
  437.     #define kLeftObeliskV        250
  438.     #define kRightObeliskH        468
  439.     #define kRightObeliskV        250
  440.     #define kWander                16
  441.     
  442.     short        i, leftDeltaH, rightDeltaH, leftDeltaV, rightDeltaV, range;
  443.     
  444.     leftDeltaH = h - kLeftObeliskH;                // determine the h and v distances between…
  445.     rightDeltaH = h - kRightObeliskH;            // obelisks and the target point
  446.     leftDeltaV = v - kLeftObeliskV;
  447.     rightDeltaV = v - kRightObeliskV;
  448.     
  449.     for (i = 0; i < kNumLightningPts; i++)        // calculate an even spread of points between…
  450.     {                                            // obelisk tips and the target point
  451.         leftLightningPts[i].h = (leftDeltaH * i) / (kNumLightningPts - 1) + kLeftObeliskH;
  452.         leftLightningPts[i].v = (leftDeltaV * i) / (kNumLightningPts - 1) + kLeftObeliskV;
  453.         rightLightningPts[i].h = (rightDeltaH * i) / (kNumLightningPts - 1) + kRightObeliskH;
  454.         rightLightningPts[i].v = (rightDeltaV * i) / (kNumLightningPts - 1) + kRightObeliskV;
  455.     }
  456.     
  457.     range = kWander * 2 + 1;                    // randomly scatter the points vertically…
  458.     for (i = 1; i < kNumLightningPts - 1; i++)    // but NOT the 1st or last points
  459.     {
  460.         leftLightningPts[i].v += RandomInt(range) - kWander;
  461.         rightLightningPts[i].v += RandomInt(range) - kWander;
  462.     }
  463. }
  464.  
  465. //--------------------------------------------------------------  FlashObelisks
  466.  
  467. void FlashObelisks (Boolean flashThem)
  468. {    
  469.     if (flashThem)
  470.     {
  471.         CopyBits(&((GrafPtr)obeliskSrcMap)->portBits, 
  472.                 &(((GrafPtr)mainWindow)->portBits), 
  473.                 &obeliskRects[0], &obeliskRects[2], 
  474.                 srcCopy, 0L);
  475.         CopyBits(&((GrafPtr)obeliskSrcMap)->portBits, 
  476.                 &(((GrafPtr)mainWindow)->portBits), 
  477.                 &obeliskRects[1], &obeliskRects[3], 
  478.                 srcCopy, 0L);
  479.     }
  480.     else
  481.     {
  482.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  483.                 &(((GrafPtr)mainWindow)->portBits), 
  484.                 &obeliskRects[2], &obeliskRects[2], 
  485.                 srcCopy, 0L);
  486.         CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  487.                 &(((GrafPtr)mainWindow)->portBits), 
  488.                 &obeliskRects[3], &obeliskRects[3], 
  489.                 srcCopy, 0L);
  490.     }
  491. }
  492.  
  493. //--------------------------------------------------------------  StrikeLightning
  494.  
  495. void StrikeLightning (void)
  496. {
  497.     short        i;
  498.     
  499.     SetPort((GrafPtr)mainWindow);
  500.     PenSize(1, 2);                            // use a tall pen
  501.     PenMode(patXor);                        // use XOR mode
  502.                                             // draw lightning bolts with inverted pen
  503.     MoveTo(leftLightningPts[0].h, leftLightningPts[0].v);
  504.     for (i = 0; i < kNumLightningPts - 1; i++)
  505.     {
  506.         MoveTo(leftLightningPts[i].h, leftLightningPts[i].v);
  507.         LineTo(leftLightningPts[i + 1].h - 1, leftLightningPts[i + 1].v);
  508.     }
  509.     
  510.     MoveTo(rightLightningPts[0].h, rightLightningPts[0].v);
  511.     for (i = 0; i < kNumLightningPts - 1; i++)
  512.     {
  513.         MoveTo(rightLightningPts[i].h, rightLightningPts[i].v);
  514.         LineTo(rightLightningPts[i + 1].h - 1, rightLightningPts[i + 1].v);
  515.     }
  516.     
  517.     PenNormal();
  518. }
  519.  
  520. //--------------------------------------------------------------  DumpBackToWorkMap
  521.  
  522. void DumpBackToWorkMap (void)
  523. {
  524.     CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  525.             &((GrafPtr)workSrcMap)->portBits, 
  526.             &backSrcRect, &backSrcRect, srcCopy, 0L);
  527. }
  528.  
  529. //--------------------------------------------------------------  DumpBackToWorkMap
  530.  
  531. void DumpMainToWorkMap (void)
  532. {
  533.     CopyBits(&(((GrafPtr)mainWindow)->portBits), 
  534.             &((GrafPtr)workSrcMap)->portBits, 
  535.             &backSrcRect, &backSrcRect, srcCopy, 0L);
  536. }
  537.  
  538. //--------------------------------------------------------------  QuickUnionRect
  539.  
  540. void QuickUnionRect (Rect *rect1, Rect *rect2, Rect *whole)
  541. {
  542.     if (rect1->left < rect2->left)
  543.     {
  544.         whole->left = rect1->left;
  545.         whole->right = rect2->right;
  546.     }
  547.     else
  548.     {
  549.         whole->left = rect2->left;
  550.         whole->right = rect1->right;
  551.     }
  552.     
  553.     if (rect1->top < rect2->top)
  554.     {
  555.         whole->top = rect1->top;
  556.         whole->bottom = rect2->bottom;
  557.     }
  558.     else
  559.     {
  560.         whole->top = rect2->top;
  561.         whole->bottom = rect1->bottom;
  562.     }
  563. }
  564.  
  565. //--------------------------------------------------------------  AddToUpdateRects
  566.  
  567. void AddToUpdateRects (Rect *theRect)
  568. {
  569.     if (whichList)
  570.     {
  571.         if (numUpdateRects1 < (kMaxNumUpdateRects - 1))
  572.         {
  573.             updateRects1[numUpdateRects1] = *theRect;
  574.             numUpdateRects1++;
  575.             if (updateRects1[numUpdateRects1].left < 0)
  576.                 updateRects1[numUpdateRects1].left = 0;
  577.             else if (updateRects1[numUpdateRects1].right > 640)
  578.                 updateRects1[numUpdateRects1].right = 640;
  579.             if (updateRects1[numUpdateRects1].top < 0)
  580.                 updateRects1[numUpdateRects1].top = 0;
  581.             else if (updateRects1[numUpdateRects1].bottom > 480)
  582.                 updateRects1[numUpdateRects1].bottom = 480;
  583.         }
  584.     }
  585.     else
  586.     {
  587.         if (numUpdateRects2 < (kMaxNumUpdateRects - 1))
  588.         {
  589.             updateRects2[numUpdateRects2] = *theRect;
  590.             numUpdateRects2++;
  591.             if (updateRects2[numUpdateRects2].left < 0)
  592.                 updateRects2[numUpdateRects2].left = 0;
  593.             else if (updateRects2[numUpdateRects2].right > 640)
  594.                 updateRects2[numUpdateRects2].right = 640;
  595.             if (updateRects2[numUpdateRects2].top < 0)
  596.                 updateRects2[numUpdateRects2].top = 0;
  597.             else if (updateRects2[numUpdateRects2].bottom > 480)
  598.                 updateRects2[numUpdateRects2].bottom = 480;
  599.         }
  600.     }
  601. }
  602.  
  603. //--------------------------------------------------------------  CheckPlayerWrapAround
  604.  
  605. void CheckPlayerWrapAround (void)
  606. {
  607.     Rect        wrapRect, wasWrapRect, src;
  608.     
  609.     if (thePlayer.dest.right > 640)
  610.     {
  611.         thePlayer.wrapping = TRUE;
  612.         wrapRect = thePlayer.dest;
  613.         wrapRect.left -= 640;
  614.         wrapRect.right -= 640;
  615.         
  616.         wasWrapRect = thePlayer.wasDest;
  617.         wasWrapRect.left -= 640;
  618.         wasWrapRect.right -= 640;
  619.         
  620.         if (thePlayer.mode == kBones)
  621.         {
  622.             src = playerRects[thePlayer.srcNum];
  623.             src.bottom = src.top + thePlayer.frame;
  624.             CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  625.                     &((GrafPtr)playerMaskMap)->portBits, 
  626.                     &((GrafPtr)workSrcMap)->portBits, 
  627.                     &src, &src, &wrapRect);
  628.         }
  629.         else
  630.         {
  631.             CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  632.                     &((GrafPtr)playerMaskMap)->portBits, 
  633.                     &((GrafPtr)workSrcMap)->portBits, 
  634.                     &playerRects[thePlayer.srcNum], 
  635.                     &playerRects[thePlayer.srcNum], 
  636.                     &wrapRect);
  637.         }
  638.         thePlayer.wrap = wrapRect;
  639.         AddToUpdateRects(&wrapRect);
  640.     }
  641.     else if (thePlayer.dest.left < 0)
  642.     {
  643.         thePlayer.wrapping = TRUE;
  644.         wrapRect = thePlayer.dest;
  645.         wrapRect.left += 640;
  646.         wrapRect.right += 640;
  647.         
  648.         wasWrapRect = thePlayer.wasDest;
  649.         wasWrapRect.left += 640;
  650.         wasWrapRect.right += 640;
  651.         
  652.         if (thePlayer.mode == kBones)
  653.         {
  654.             src = playerRects[thePlayer.srcNum];
  655.             src.bottom = src.top + thePlayer.frame;
  656.             CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  657.                     &((GrafPtr)playerMaskMap)->portBits, 
  658.                     &((GrafPtr)workSrcMap)->portBits, 
  659.                     &src, &src, &wrapRect);
  660.         }
  661.         else
  662.         {
  663.             CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  664.                     &((GrafPtr)playerMaskMap)->portBits, 
  665.                     &((GrafPtr)workSrcMap)->portBits, 
  666.                     &playerRects[thePlayer.srcNum], 
  667.                     &playerRects[thePlayer.srcNum], 
  668.                     &wrapRect);
  669.         }
  670.         thePlayer.wrap = wrapRect;
  671.         AddToUpdateRects(&wrapRect);
  672.     }
  673.     else
  674.         thePlayer.wrapping = FALSE;
  675. }
  676.  
  677. //--------------------------------------------------------------  DrawTorches
  678.  
  679. void DrawTorches (void)
  680. {
  681.     short        who;
  682.     
  683.     who = RandomInt(4);
  684.     if (evenFrame)
  685.     {
  686.         CopyBits(&((GrafPtr)flameSrcMap)->portBits, 
  687.                 &((GrafPtr)workSrcMap)->portBits, 
  688.                 &flameRects[who], &flameDestRects[0], srcCopy, 0L);
  689.         AddToUpdateRects(&flameDestRects[0]);
  690.     }
  691.     else
  692.     {
  693.         CopyBits(&((GrafPtr)flameSrcMap)->portBits, 
  694.                 &((GrafPtr)workSrcMap)->portBits, 
  695.                 &flameRects[who], &flameDestRects[1], srcCopy, 0L);
  696.         AddToUpdateRects(&flameDestRects[1]);
  697.     }
  698. }
  699.  
  700. //--------------------------------------------------------------  DrawHand
  701.  
  702. void DrawHand (void)
  703. {
  704.     if (theHand.mode == kOutGrabeth)
  705.     {
  706.         CopyMask(&((GrafPtr)handSrcMap)->portBits, 
  707.                 &((GrafPtr)handMaskMap)->portBits, 
  708.                 &((GrafPtr)workSrcMap)->portBits, 
  709.                 &handRects[0], 
  710.                 &handRects[0], 
  711.                 &theHand.dest);
  712.         AddToUpdateRects(&theHand.dest);
  713.     }
  714.     else if (theHand.mode == kClutching)
  715.     {
  716.         CopyMask(&((GrafPtr)handSrcMap)->portBits, 
  717.                 &((GrafPtr)handMaskMap)->portBits, 
  718.                 &((GrafPtr)workSrcMap)->portBits, 
  719.                 &handRects[1], 
  720.                 &handRects[1], 
  721.                 &theHand.dest);
  722.         AddToUpdateRects(&theHand.dest);
  723.     }
  724. }
  725.  
  726. //--------------------------------------------------------------  DrawEye
  727.  
  728. void DrawEye (void)
  729. {
  730.     if (theEye.mode == kStalking)
  731.     {
  732.         CopyMask(&((GrafPtr)eyeSrcMap)->portBits, 
  733.                 &((GrafPtr)eyeMaskMap)->portBits, 
  734.                 &((GrafPtr)workSrcMap)->portBits, 
  735.                 &eyeRects[theEye.srcNum], 
  736.                 &eyeRects[theEye.srcNum], 
  737.                 &theEye.dest);
  738.         AddToUpdateRects(&theEye.dest);
  739.     }
  740. }
  741.  
  742. //--------------------------------------------------------------  CopyAllRects
  743.  
  744. void CopyAllRects (void)
  745. {
  746.     short        i;
  747.     
  748.     if (whichList)
  749.     {
  750.         for (i = 0; i < numUpdateRects1; i++)
  751.         {
  752.             CopyBits(&((GrafPtr)workSrcMap)->portBits, 
  753.                     &(((GrafPtr)mainWindow)->portBits), 
  754.                     &updateRects1[i], &updateRects1[i], srcCopy, playRgn);
  755.         }
  756.         
  757.         for (i = 0; i < numUpdateRects2; i++)
  758.         {
  759.             CopyBits(&((GrafPtr)workSrcMap)->portBits, 
  760.                     &(((GrafPtr)mainWindow)->portBits), 
  761.                     &updateRects2[i], &updateRects2[i], srcCopy, playRgn);
  762.         }
  763.         
  764.         for (i = 0; i < numUpdateRects1; i++)
  765.         {
  766.             CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  767.                     &((GrafPtr)workSrcMap)->portBits, 
  768.                     &updateRects1[i], &updateRects1[i], srcCopy, playRgn);
  769.         }
  770.         
  771.         numUpdateRects2 = 0;
  772.         whichList = !whichList;
  773.     }
  774.     else
  775.     {
  776.         for (i = 0; i < numUpdateRects2; i++)
  777.         {
  778.             CopyBits(&((GrafPtr)workSrcMap)->portBits, 
  779.                     &(((GrafPtr)mainWindow)->portBits), 
  780.                     &updateRects2[i], &updateRects2[i], srcCopy, playRgn);
  781.         }
  782.         
  783.         for (i = 0; i < numUpdateRects1; i++)
  784.         {
  785.             CopyBits(&((GrafPtr)workSrcMap)->portBits, 
  786.                     &(((GrafPtr)mainWindow)->portBits), 
  787.                     &updateRects1[i], &updateRects1[i], srcCopy, playRgn);
  788.         }
  789.         
  790.         for (i = 0; i < numUpdateRects2; i++)
  791.         {
  792.             CopyBits(&((GrafPtr)backSrcMap)->portBits, 
  793.                     &((GrafPtr)workSrcMap)->portBits, 
  794.                     &updateRects2[i], &updateRects2[i], srcCopy, playRgn);
  795.         }
  796.         
  797.         numUpdateRects1 = 0;
  798.         whichList = !whichList;
  799.     }
  800. }
  801.  
  802. //--------------------------------------------------------------  DrawPlayer
  803.  
  804. void DrawPlayer (void)
  805. {
  806.     Rect        src;
  807.     
  808.     if ((evenFrame) && (thePlayer.mode == kIdle))
  809.     {
  810.         CopyMask(&((GrafPtr)idleSrcMap)->portBits, 
  811.                 &((GrafPtr)playerMaskMap)->portBits, 
  812.                 &((GrafPtr)workSrcMap)->portBits, 
  813.                 &idleSrcRect, 
  814.                 &playerRects[thePlayer.srcNum], 
  815.                 &thePlayer.dest);
  816.     }
  817.     else if (thePlayer.mode == kBones)
  818.     {
  819.         src = playerRects[thePlayer.srcNum];
  820.         src.bottom = src.top + thePlayer.frame;
  821.         CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  822.                 &((GrafPtr)playerMaskMap)->portBits, 
  823.                 &((GrafPtr)workSrcMap)->portBits, 
  824.                 &src, &src, &thePlayer.dest);
  825.     }
  826.     else
  827.     {
  828.         CopyMask(&((GrafPtr)playerSrcMap)->portBits, 
  829.                 &((GrafPtr)playerMaskMap)->portBits, 
  830.                 &((GrafPtr)workSrcMap)->portBits, 
  831.                 &playerRects[thePlayer.srcNum], 
  832.                 &playerRects[thePlayer.srcNum], 
  833.                 &thePlayer.dest);
  834.     }
  835.     AddToUpdateRects(&thePlayer.dest);
  836.     
  837.     thePlayer.wasH = thePlayer.h;
  838.     thePlayer.wasV = thePlayer.v;
  839.     
  840.     thePlayer.wasDest = thePlayer.dest;
  841. }
  842.  
  843. //--------------------------------------------------------------  CheckEnemyWrapAround
  844.  
  845. void CheckEnemyWrapAround (short who)
  846. {
  847.     Rect        wrapRect, wasWrapRect, src;
  848.     
  849.     if (theEnemies[who].dest.right > 640)
  850.     {
  851.         wrapRect = theEnemies[who].dest;
  852.         wrapRect.left -= 640;
  853.         wrapRect.right -= 640;
  854.         
  855.         wasWrapRect = theEnemies[who].wasDest;
  856.         wasWrapRect.left -= 640;
  857.         wasWrapRect.right -= 640;
  858.         
  859.         if ((theEnemies[who].mode == kFalling) || (theEnemies[who].mode == kEggTimer))
  860.         {
  861.             if ((theEnemies[who].mode == kEggTimer) && (theEnemies[who].frame < 24))
  862.             {
  863.                 src = eggSrcRect;
  864.                 src.bottom = src.top + theEnemies[who].frame;
  865.             }
  866.             else
  867.                 src = eggSrcRect;
  868.             CopyMask(&((GrafPtr)eggSrcMap)->portBits, 
  869.                     &((GrafPtr)eggMaskMap)->portBits, 
  870.                     &((GrafPtr)workSrcMap)->portBits, 
  871.                     &src, &src, &wrapRect);
  872.         }
  873.         else
  874.         {
  875.             CopyMask(&((GrafPtr)enemyFlySrcMap)->portBits, 
  876.                     &((GrafPtr)enemyFlyMaskMap)->portBits, 
  877.                     &((GrafPtr)workSrcMap)->portBits, 
  878.                     &enemyRects[theEnemies[who].srcNum], 
  879.                     &enemyRects[theEnemies[who].srcNum], 
  880.                     &wrapRect);
  881.         }
  882.         AddToUpdateRects(&wrapRect);
  883.     }
  884.     else if (theEnemies[who].dest.left < 0)
  885.     {
  886.         wrapRect = theEnemies[who].dest;
  887.         wrapRect.left += 640;
  888.         wrapRect.right += 640;
  889.         
  890.         wasWrapRect = theEnemies[who].wasDest;
  891.         wasWrapRect.left += 640;
  892.         wasWrapRect.right += 640;
  893.         if ((theEnemies[who].mode == kFalling) || (theEnemies[who].mode == kEggTimer))
  894.         {
  895.             if ((theEnemies[who].mode == kEggTimer) && (theEnemies[who].frame < 24))
  896.             {
  897.                 src = eggSrcRect;
  898.                 src.bottom = src.top + theEnemies[who].frame;
  899.             }
  900.             else
  901.                 src = eggSrcRect;
  902.             CopyMask(&((GrafPtr)eggSrcMap)->portBits, 
  903.                     &((GrafPtr)eggMaskMap)->portBits, 
  904.                     &((GrafPtr)workSrcMap)->portBits, 
  905.                     &src, &src, &wrapRect);
  906.         }
  907.         else
  908.         {
  909.             CopyMask(&((GrafPtr)enemyFlySrcMap)->portBits, 
  910.                     &((GrafPtr)enemyFlyMaskMap)->portBits, 
  911.                     &((GrafPtr)workSrcMap)->portBits, 
  912.                     &enemyRects[theEnemies[who].srcNum], 
  913.                     &enemyRects[theEnemies[who].srcNum], 
  914.                     &wrapRect);
  915.         }
  916.         AddToUpdateRects(&wrapRect);
  917.     }
  918. }
  919.  
  920. //--------------------------------------------------------------  DrawEnemies
  921.  
  922. void DrawEnemies (void)
  923. {
  924.     Rect        src;
  925.     short        i;
  926.     
  927.     for (i = 0; i < numEnemies; i++)
  928.     {
  929.         switch (theEnemies[i].mode)
  930.         {
  931.             case kSpawning:
  932.             src = enemyRects[theEnemies[i].srcNum];
  933.             src.bottom = src.top + theEnemies[i].frame;
  934.             CopyMask(&((GrafPtr)enemyWalkSrcMap)->portBits, 
  935.                     &((GrafPtr)enemyWalkMaskMap)->portBits, 
  936.                     &((GrafPtr)workSrcMap)->portBits, 
  937.                     &src, &src, &theEnemies[i].dest);
  938.             AddToUpdateRects(&theEnemies[i].dest);
  939.             theEnemies[i].wasDest = theEnemies[i].dest;
  940.             theEnemies[i].wasH = theEnemies[i].h;
  941.             theEnemies[i].wasV = theEnemies[i].v;
  942.             break;
  943.             
  944.             case kFlying:
  945.             CopyMask(&((GrafPtr)enemyFlySrcMap)->portBits, 
  946.                     &((GrafPtr)enemyFlyMaskMap)->portBits, 
  947.                     &((GrafPtr)workSrcMap)->portBits, 
  948.                     &enemyRects[theEnemies[i].srcNum], &enemyRects[theEnemies[i].srcNum], 
  949.                     &theEnemies[i].dest);
  950.             AddToUpdateRects(&theEnemies[i].dest);
  951.             CheckEnemyWrapAround(i);
  952.             theEnemies[i].wasDest = theEnemies[i].dest;
  953.             theEnemies[i].wasH = theEnemies[i].h;
  954.             theEnemies[i].wasV = theEnemies[i].v;
  955.             break;
  956.             
  957.             case kWalking:
  958.             CopyMask(&((GrafPtr)enemyWalkSrcMap)->portBits, 
  959.                     &((GrafPtr)enemyWalkMaskMap)->portBits, 
  960.                     &((GrafPtr)workSrcMap)->portBits, 
  961.                     &enemyRects[theEnemies[i].srcNum], &enemyRects[theEnemies[i].srcNum], 
  962.                     &theEnemies[i].dest);
  963.             AddToUpdateRects(&theEnemies[i].dest);
  964.             theEnemies[i].wasDest = theEnemies[i].dest;
  965.             theEnemies[i].wasH = theEnemies[i].h;
  966.             theEnemies[i].wasV = theEnemies[i].v;
  967.             break;
  968.             
  969.             case kFalling:
  970.             CopyMask(&((GrafPtr)eggSrcMap)->portBits, 
  971.                     &((GrafPtr)eggMaskMap)->portBits, 
  972.                     &((GrafPtr)workSrcMap)->portBits, 
  973.                     &eggSrcRect, &eggSrcRect, &theEnemies[i].dest);
  974.             AddToUpdateRects(&theEnemies[i].dest);
  975.             CheckEnemyWrapAround(i);
  976.             theEnemies[i].wasDest = theEnemies[i].dest;
  977.             theEnemies[i].wasH = theEnemies[i].h;
  978.             theEnemies[i].wasV = theEnemies[i].v;
  979.             break;
  980.             
  981.             case kEggTimer:
  982.             if (theEnemies[i].frame < 24)
  983.             {
  984.                 src = eggSrcRect;
  985.                 src.bottom = src.top + theEnemies[i].frame;
  986.             }
  987.             else
  988.                 src = eggSrcRect;
  989.             CopyMask(&((GrafPtr)eggSrcMap)->portBits, 
  990.                     &((GrafPtr)eggMaskMap)->portBits, 
  991.                     &((GrafPtr)workSrcMap)->portBits, 
  992.                     &src, &src, &theEnemies[i].dest);
  993.             AddToUpdateRects(&theEnemies[i].dest);
  994.             CheckEnemyWrapAround(i);
  995.             theEnemies[i].wasDest = theEnemies[i].dest;
  996.             theEnemies[i].wasH = theEnemies[i].h;
  997.             theEnemies[i].wasV = theEnemies[i].v;
  998.             break;
  999.         }
  1000.     }
  1001. }
  1002.  
  1003. //--------------------------------------------------------------  DrawFrame
  1004.  
  1005. void DrawFrame (void)
  1006. {
  1007.     
  1008.     DrawTorches();
  1009.     DrawHand();
  1010.     DrawEye();
  1011.     DrawPlayer();
  1012.     CheckPlayerWrapAround();
  1013.     DrawEnemies();
  1014.     CopyAllRects();
  1015. }
  1016.  
  1017.